package c05.jmm;

import static util.Sleeper.sleep;

public class JMMPrint {
    // 易变
    static boolean run = true;

    public static void main(String[] args) {
        Thread t = new Thread(() -> {
//            while (run) {
//                // 为什么run不是volatile变量也能正确读取到run的新值？
//                System.out.println(run);
//            }

            while (true) {
                // 为什么run不是volatile变量也能正确读取到run的新值？
                System.out.println(String.valueOf(System.currentTimeMillis()) + "  " + run);
                if (!run) {
                    System.out.println(String.valueOf(System.currentTimeMillis()) + "  " + run);
                    break;
                }
            }
        });
        t.start();

        sleep(1);
        run = false; // 线程t不会如预想的停下来

        /*
        1.初始状态，t线程刚开始从主存读取了run的值到工作内存
        2.因为t线程要频繁从主内存读取run的值，jit编译器会将run的值缓存至自己的工作内存中的高速缓存中，减少对主存中run的访问，提高效率
        3.1s后main线程修改了run的值，但并没有机制让它同步至高速缓存，因此t线程从高速缓存中取到的值始终是旧值

        解决方案：synchronized, volatile, System.out.println
         */
    }
}
